﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Criterion;

namespace Commander.DataLayer.Repositories {
  public interface IRepository<T> where T : class {
    bool AddItem(T item);
    bool RemoveItem(T item);
    bool RemoveItemById(Guid Id);
    bool UpdateItem(T item);
    T RetrieveItemById(Guid Id);
    IList<T> RetrieveAllItems();
    IEnumerable<T> RetrieveEntities(Func<T, bool> lambda);
  }

  public class DomainRepository<T> : IRepository<T> where T : DomainBase {

    public virtual bool AddItem(T item) {
      if (RetrieveItemById(item.Id) != null) {
        return false;
      }

      using (ISession session = NHibernateSessionHelper.OpenSession())
      using (ITransaction transaction = session.BeginTransaction()) {
        session.Save(item);
        transaction.Commit();
        return transaction.WasCommitted;
      }
    }

    public bool RemoveItem(T item) {
      using (ISession session = NHibernateSessionHelper.OpenSession())
      using (ITransaction transaction = session.BeginTransaction()) {
        session.Delete(item);
        transaction.Commit();
        return transaction.WasCommitted;
      }
    }

    public IEnumerable<T> RetrieveEntities(Func<T, bool> lambda) {
      using (ISession session = NHibernateSessionHelper.OpenSession()) {
        return session.CreateCriteria(typeof(T)).List<T>().Where(lambda);
      }
    }

    public bool UpdateItem(T item) {
      using (ISession session = NHibernateSessionHelper.OpenSession())
      using (ITransaction transaction = session.BeginTransaction()) {
        session.Update(item);
        transaction.Commit();
        return transaction.WasCommitted;
      }
    }

    public T RetrieveItemById(Guid Id) {
      using (ISession session = NHibernateSessionHelper.OpenSession()) {
        return session.CreateCriteria(typeof(T))
           .Add(Restrictions.Eq("Id", Id))
          .UniqueResult<T>();
      }
    }

    public IList<T> RetrieveAllItems() {
      using (ISession session = NHibernateSessionHelper.OpenSession()) {
        return session.CreateCriteria(typeof(T))
          .List<T>();
      }
    }

    public bool RemoveItemById(Guid Id) {
      var toDelete = RetrieveItemById(Id);
      if (toDelete != null) return RemoveItem(toDelete);
      else return false;
    }
  }


}
